package com.gsbelarus.gedemin.salary.fragment.payslip;

import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;

import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.gsbelarus.gedemin.lib.ui.fragment.FragmentModel;
import com.gsbelarus.gedemin.salary.App;
import com.gsbelarus.gedemin.salary.R;
import com.gsbelarus.gedemin.salary.adapter.PayslipDetailAdapter;
import com.gsbelarus.gedemin.salary.database.RealmHelper;
import com.gsbelarus.gedemin.salary.entity.PayslipDetailCard;
import com.gsbelarus.gedemin.salary.entity.model.PayslipBenefitModel;
import com.gsbelarus.gedemin.salary.entity.model.PayslipDeductionModel;
import com.gsbelarus.gedemin.salary.entity.model.PayslipItemModel;
import com.gsbelarus.gedemin.salary.entity.model.PayslipModel;
import com.gsbelarus.gedemin.salary.ui.AutofitRecyclerView;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import io.realm.Realm;
import io.realm.RealmResults;

public class PayslipDetailFragment extends FragmentModel implements PageTitleInterface {

    private Calendar date;
    private PayslipDetailAdapter adapter;

    private RealmHelper realmHelper;

    @Override
    public int getViewResource() {
        return R.layout.payslip_detail;
    }

    @Override
    public int getPageTitleResource() {
        return R.string.payslip_detail;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        realmHelper = new RealmHelper(Realm.getInstance(context));
        date = Calendar.getInstance();
        adapter = new PayslipDetailAdapter(context, realmHelper);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        realmHelper.getRealm().close();
    }

    @Override
    public void onCreateViewFragment(View rootView) {
        super.onCreateViewFragment(rootView);

        AutofitRecyclerView cardsRecView = (AutofitRecyclerView) rootView.findViewById(R.id.payslip_recycler_view);
        final StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
        cardsRecView.setLayoutManager(manager);
        cardsRecView.setHasFixedSize(true);
        cardsRecView.setColumnWidth(getActivity().getResources().getDimension(R.dimen.payslip_detail_card_width));
        cardsRecView.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                super.getItemOffsets(outRect, view, parent, state);
                int space = (int) (2f * context.getResources().getDisplayMetrics().density);

                outRect.top = space;
                outRect.left = space;
                outRect.right = space;
                outRect.bottom = space;
            }
        });
        cardsRecView.setAdapter(adapter);

        if (isContainsParams()) {
            date.set(argumentsHelper.selectedYear, argumentsHelper.selectedMonth - 1, 1);
        }
    }

    /**
     * Чтение данных из БД в новом потоке
     */
    @Override
    public void readDataBase() {
    }

    /**
     * Метод вызывается после чтения данных из БД или при смене ориентации экрана.
     * Может быть вызван до окончания выполнения потока для запроса данных из БД, поэтому следует проверять данные на null.
     * Служит для инициализации View данными
     *
     * @param rootView корневое View
     */
    @Override
    public void initView(View rootView) {
        adapter.clear();
        if (!isContainsParams()) {
            List<Calendar> possibleDates = realmHelper.getPayslipPossibleDatesList();

            date = possibleDates.get(possibleDates.size() - 1);
        }
        PayslipModel payslipModel = realmHelper.getPayslip(date);

        if (payslipModel != null) {
            List<PayslipDetailCard> list = new ArrayList<>();
            RealmResults<PayslipItemModel> debitList = realmHelper.getDebitList(payslipModel);
            RealmResults<PayslipItemModel> creditList = realmHelper.getCreditList(payslipModel);
            RealmResults<PayslipItemModel> taxList = realmHelper.getTaxesList(payslipModel);

            double prepayment = realmHelper.getPrepaymentSum(payslipModel);
            //TODO long
            double deductionSum = 0;
            double benefitSum = 0;

            /** общая сумма начислений и удержаний */
            if (payslipModel.getDeductions() != null)
                deductionSum = payslipModel.getDeductions().where().sumDouble("sum");
            if (payslipModel.getBenefits() != null)
                benefitSum = payslipModel.getBenefits().where().findAll().sum("sum").doubleValue();

            if (!debitList.isEmpty()) {
                HashMap<String, Double> items = new HashMap<>();
                for (PayslipItemModel item : debitList) {
                    items.put(item.getName(), item.getDebit());
                }
                list.add(new PayslipDetailCard("НАЧИСЛЕНИЯ", debitList.sum("debit").doubleValue(), sortByComparatorValues(items, false)));
            }
            if (!creditList.isEmpty() || prepayment > 0) {
                HashMap<String, Double> items = new HashMap<>();
                for (PayslipItemModel item : creditList) {
                    items.put(item.getName(), item.getCredit());
                }
                if (prepayment > 0)
                    items.put("Аванс", prepayment);
                list.add(new PayslipDetailCard("УДЕРЖАНИЯ", creditList.sum("credit").doubleValue() + prepayment, sortByComparatorValues(items, false)));
            }
            if (!taxList.isEmpty()) {
                HashMap<String, Double> items = new HashMap<>();
                for (PayslipItemModel item : taxList) {
                    items.put(item.getName(), item.getCredit());
                }
                list.add(new PayslipDetailCard("НАЛОГИ", taxList.sum("credit").doubleValue(), sortByComparatorValues(items, false)));
            }
            if (!payslipModel.getDeductions().isEmpty()) {
                HashMap<String, Double> items = new HashMap<>();
                for (PayslipDeductionModel item : payslipModel.getDeductions()) {
                    items.put(item.getName(), item.getSum());
                }
                list.add(new PayslipDetailCard("ВЫЧЕТЫ", deductionSum, sortByComparatorValues(items, false)));
            }
            if (!payslipModel.getBenefits().isEmpty()) {
                HashMap<String, Double> items = new HashMap<>();
                for (PayslipBenefitModel item : payslipModel.getBenefits()) {
                    items.put(item.getName(), item.getSum());
                }
                list.add(new PayslipDetailCard("ЛЬГОТЫ", benefitSum, sortByComparatorValues(items, false)));
            }

            adapter.setList(date, list);
        }
    }

    private Map<String, Double> sortByComparatorValues(Map<String, Double> unsortMap, final boolean orderASC) { // true - ASC, false - DESC
        List<Map.Entry<String, Double>> list = new LinkedList<>(unsortMap.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, Double>>() {
            public int compare(Map.Entry<String, Double> o1,
                               Map.Entry<String, Double> o2) {
                if (orderASC) {
                    return o1.getValue().compareTo(o2.getValue());
                } else {
                    return o2.getValue().compareTo(o1.getValue());

                }
            }
        });

        Map<String, Double> sortedMap = new LinkedHashMap<>();
        for (Map.Entry<String, Double> entry : list) {
            sortedMap.put(entry.getKey(), entry.getValue());
        }

        return sortedMap;
    }

    @Override
    public void onResume() {
        super.onResume();
        Tracker tracker = ((App) getActivity().getApplication()).getTracker(App.TrackerName.APP_TRACKER);
        tracker.setScreenName(getClass().getSimpleName());
        tracker.send(new HitBuilders.AppViewBuilder().build());
    }
}
